﻿using System;
using System.Collections.Generic;
using TableDef;
using UnityEngine;
using UnityEngine.UI;
/*
界面管理器
界面分为几个大层,现阶段只开放了10层，如果需要修改，改m_nLayerCounter即可

0: 战斗飘字，场景特效
1: 主界面，
2：对话界面
3, 弹出式界面
4, 通用信息条，显示金币，被弹出式界面呼出
5, 弹出式提示框层




每一小层panelbase的 RenderOrder 会以10为增量增长，这是为了给这个窗口里的 sortorder 预留的，子节点里如果加了sortorder脚本，其中填的参数order就是相对
父节点的renderorder的增量，这样保证每一个窗口里的层级显示正常。
每次需要跟新层次的时候，调用 DoResetWindow 来重新排序，保证层级的正确性

每个窗口会有几个接口导出给lua， 
OnStart()       这个每次只会调用一次，如果是缓存的窗口，就只会有一次，用来注册一些消息接口，变量控件初始化
OnEnable()      这个每次开启都会调用，一般用来初始化一些即时的数据，比如创建模型一类的
OnShow()        这个每次开启都会调用，用来做一些关联的窗口操作，比如开启一个别的窗口，不做本身的逻辑处理
OnParam()       这个每次开启都会调用，用来传进一个字符串参数，根据参数做一些特殊处理

OnDisalbe()     这个是删除窗口后调用的，一般不要在这里面写东西，特别是窗口操作
OnHide()        这个是每次正常关闭都会调用的， 用来处理onshow对应的窗口操作
注意!!!!!
每个窗口的ondisable里不能调用开启和关闭其他窗口的操作，因为这个函数在release的时候会被调用，一旦操作别的窗口，会导致窗口逻辑序列里的数据混乱。


*/
namespace SG
{
    public enum SystemEventDef
    {
        System_Open_Window = -1000,
        System_Close_Window,
    }

    public class UIMgr : ModifyBase
    {
        #region 静态接口
        private static UIMgr m_instance;
        public static UIMgr Instance()
        {
            if (m_instance == null)
            {
                m_instance = new UIMgr();
                m_instance.DoInit();
            }
            return m_instance;
        }
        #endregion


        int m_nLayerOffsest = 1000; // 每大层的范围
        int m_nLayerCounter = 11; // 每小蹭的范围(第 11 层 为loading 层)
        int m_CanReleaseCounter = 10; //可以 release 统一清理的范围

        public int mNavigateType = 0;
        public int mNavigateShowType = 0;

        // 窗口表数据结构
        //public class WindowDataDef : ResDataBase
        //{
        //    public string m_strWindowName;      // 窗口关键字
        //    public int m_nLayer;                // 所在层
        //    public int m_nToggleGroup;          // 所在互斥组,同组的界面同时只能显示一个
        //    public bool m_bPreload;             // 是否缓存
        //    public bool m_bCache;               // 是否关闭后保存
        //    public string m_strResPath;         // 资源路径


        //    protected override void OnInit()
        //    {
        //        m_nID = GetInt("id");
        //        m_strWindowName = GetString("panelName");
        //        m_nLayer = GetInt("Layer");
        //        m_strResPath = GetString("prefabPath");
        //        m_bPreload = GetBool("preload");
        //        m_nToggleGroup = GetInt("toggleGroup");
        //        m_bCache = GetBool("cache");

        //    }
        //}

        public enum UICameraType
        {
            Camera2d,
        }
        public enum LayerType
        {
            Main,
            AutoBattle,
            Normal,
            Navigation,
            PopWin,
            NetWin,
            Other
        }
        /*
        层级数据，
        每一个层级都会有个显示的列表[m_UIList]和缓存列表[m_TmpList]，
        每次开启窗口的时候，如果缓存列表里有，就会从缓存列表里取出，放到显示列表里，如果没有，创建一个，放到缓存列表里，然后在去除放到显示列表里
        关闭窗口的时候，判断窗口是否需要缓存，如果需要，就放回缓存列表，否则就直接删除
        */
        class UICore
        {
            bool m_bHideVisible = false;
            public UICore(int nZero)
            {
                m_nLayerZero = nZero;
                m_UIList = new List<PanelBase>();
                m_TmpList = new List<PanelBase>();
            }
            public void SetEnableHideVisible(bool bEnable)
            {
                m_bHideVisible = bEnable;
            }
            public void Clear()
            {
                m_UIList.Clear();
                // 这里tmplist不清除，
            }


            int m_nLayerZero; // 这个组的初始层数
            PanelBase m_LayerGroupBack = null; // 这个层默认的北京层
            List<PanelBase> m_UIList;  // 这层所显示的界面的列表
            List<PanelBase> m_TmpList; // 这一层缓存的界面列表,有的界面因为过于复杂，每次显示的时候回卡，就先缓存起来，需要的时候直接显示。

            public void SetLayerGroupBack(string strName)
            {
                // 如果这个层已经有了，就不要了
                if (strName == "")
                {
                    if (m_LayerGroupBack != null)
                        m_LayerGroupBack.DoRelease();
                    m_LayerGroupBack = null;
                    return;
                }
                if (m_LayerGroupBack)
                    return;
                OpenWindowByName(strName, true, (window) =>
                {
                    m_LayerGroupBack = window;
                    m_LayerGroupBack.DoResetOrder(m_nLayerZero);
                });

            }
            public void DoRelease()
            {
                for (int i = 0; i < m_UIList.Count; ++i)
                {
                    if (m_UIList[i] != null)
                    {
                        m_UIList[i].DoRelease();
                    }
                    //if (m_UIList[i] != null)
                    //{
                    //    m_TmpList.Add(m_UIList[i]);
                    //}

                }
                m_UIList.Clear();

                for (int i = 0; i < m_TmpList.Count;)
                {
                    if (m_TmpList[i] != null)
                        m_TmpList[i].DoRelease();
                    if (m_TmpList[i] == null)
                        m_TmpList.RemoveAt(i);
                    else
                        ++i;
                }

                if (m_LayerGroupBack)
                {
                    m_LayerGroupBack.DoRelease();
                    m_LayerGroupBack = null;
                }
            }
            public void OnDestory()
            {

            }

            // 显示本层全部缓存的窗口，一般用在主界面的显示和隐藏
            public void DoShowAll()
            {
                ClearNullWindow();
                foreach (var item in m_TmpList)
                {
                    item.DoShow();
                    m_UIList.Add(item);
                }
                m_TmpList.Clear();
            }
            // 关闭本层所有窗口，一般用来关闭主界面和关闭所有弹出式界面
            public void DoHideAll(bool bSave)
            {
                ClearNullWindow();
                foreach (var item in m_UIList)
                {
                    if (item.DoHide(bSave))
                    {
                        m_TmpList.Add(item);
                    }
                }
                m_UIList.Clear();
            }

            public bool IsHaveWindowShow()
            {
                foreach (var item in m_UIList)
                {
                    if (item.gameObject.activeSelf)
                        return true;
                }
                return false;
            }

            // 判断一个窗口是否开启了。
            // 只要是再 m_UIList 里，就一定是显示的
            public bool IsWindowOpen(string strName)
            {
                foreach (var item in m_UIList)
                {
                    if (item.PanelName == strName)
                    {
                        if (item.gameObject.activeSelf)
                            return true;
                        return false;
                    }
                }
                return false;
            }
            public void EnableGraphicRaycaster(bool enable)
            {
                foreach (var item in m_UIList)
                {
                    var gr = item.GetComponent<GraphicRaycaster>();
                    if (gr != null)
                        gr.enabled = enable;
                }
                if (m_LayerGroupBack)
                {
                    var gr = m_LayerGroupBack.GetComponent<GraphicRaycaster>();
                    if (gr != null)
                        gr.enabled = enable;
                }
            }

            public PanelBase GetHaveWindow(string strName)
            {
                // 从所有显示列表里和缓存列表里找
                foreach (var item in m_UIList)
                {
                    if (item.PanelName == strName)
                    {
                        return item;
                    }
                }
                foreach (var item in m_TmpList)
                {
                    if (item.PanelName == strName)
                    {
                        return item;
                    }
                }
                return null;
            }

            // 根据名字得到窗口
            public void OpenWindowByName(string strName, bool bCreateIfExist = true, Action<PanelBase> _callBack = null)
            {
                // 从所有显示列表里和缓存列表里找，如果没有就根据 bCreateIfExit 来创建一个
                var item = GetHaveWindow(strName);
                if (item != null)
                {
                    _callBack?.Invoke(item);
                    return;
                }
                else
                {
                    if (bCreateIfExist)
                    {
                        CreateWindow(strName, (window) =>
                        {
                            _callBack?.Invoke(window);
                        });
                        return;
                    }
                }
                _callBack?.Invoke(null);
                return;
            }

            List<t_windowdef> m_Navigation = new List<t_windowdef>();

            //创建一个窗口，并且放到缓存列表里
            void CreateWindow(string strName, Action<PanelBase> _callBack = null)
            {
                var data = UIMgr.Instance().GetTableDataByName(strName);
                var addressPath = data.m_strPrefabPath;
                try
                {
                    var window = ObjectMgr.Instance().CreateObj(addressPath);
                    if (window != null)
                    {
                        DoInitPanel(strName, window, data, _callBack);
                    }
                    else
                    {
                        XKLog.LogError("CreateWindow error:" + strName);
                        _callBack?.Invoke(null);
                    }
                }
                catch (Exception e)
                {
                    XKLog.LogError("CreateWindow error:[{0}]    -->     message = [{1}]", strName, e.Message);
                }

            }

            void DoInitPanel(string strName, GameObject panelObj, t_windowdef data, Action<PanelBase> _callBack = null)
            {
                if (panelObj == null)
                {
                    XKLog.LogError("没有找到 界面路径:" + data.m_strPrefabPath);
                    _callBack?.Invoke(null);
                    return;
                }
                //if (panelObj.activeSelf)
                //{
                //    XKLog.LogError("保存该UI预设体时，名字左侧不能勾选保存！ name:" + strName);
                //}
                PanelBase panelBase = panelObj.GetComponent<PanelBase>();
                var scaler = panelObj.GetComponent<CanvasScaler>();
                scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
                //scaler.referenceResolution = new Vector2(2560, 1440);
                // scaler.matchWidthOrHeight = UIScreenAdaptationMgr.Instance().GetCanvasScalerMatch();
                panelBase.Canvas = panelBase.GetComponent<Canvas>();
                panelBase.Canvas.renderMode = RenderMode.ScreenSpaceCamera;
                panelBase.SetCamera(0);

                panelBase.PanelName = strName;
                panelBase.IsCache = data.m_bCache;
                panelBase.UIGroup = data.m_nToggleGroup;

                panelObj.transform.SetParent(UIMgr.Instance().m_UIRoot);
                RectTransform rectTrans = panelObj.transform as RectTransform;
                rectTrans.localPosition = Vector3.zero;
                ///rectTrans.sizeDelta = new Vector2(0, 0);
                rectTrans.localScale = Vector3.one;// panelObj.transform.lossyScale;
                panelObj.gameObject.SetActive(false);
                //if (panelObj.gameObject.CompareTag("Untagged"))
                //    panelObj.gameObject.SetAllChildTag("UI");
                m_TmpList.Add(panelBase);

                _callBack?.Invoke(panelBase);
            }

            // 清理掉无效窗口
            void ClearNullWindow()
            {
                for (int i = 0; i < m_UIList.Count;)
                {
                    if (m_UIList[i] == null)
                        m_UIList.RemoveAt(i);
                    else
                        ++i;
                }
                for (int i = 0; i < m_TmpList.Count;)
                {
                    if (m_TmpList[i] == null)
                        m_TmpList.RemoveAt(i);
                    else
                        ++i;
                }

            }
            // 显示窗口，需要这个窗口下的界面进行排序
            public void DoOpenWindow(string strName, EventParam param = null, Action<PanelBase> _callBack = null)
            {
                // 先检查是不是正在显示
                if (IsWindowOpen(strName))
                {
                    OpenWindowByName(strName, false, (window) =>
                    {
                        m_UIList.Remove(window);
                        m_UIList.Add(window);
                        DoResortWindow();
                        _callBack?.Invoke(window);
                    });
                    return;
                }

                ClearNullWindow();

                OpenWindowByName(strName, true, (window) =>
                {
                    if (window) // 走到这里，肯定是不显示的
                    {
                        if (window.UIGroup >= 0)
                        {
                            // 这里计算所有窗口的关闭
                            UIMgr.Instance().DoCloseWindowByGroup(window.UIGroup);
                        }
                        m_UIList.Add(window);
                        m_TmpList.Remove(window);
                        window.DoShow(param); // 显示界面                       
                        DoResortWindow();
                        XKLog.Log(" Open Window Success!!!!     [" + strName + "]");
                        var cmd = new EventParamCommon();
                        cmd.AddDataString("window", strName);
                        EventMgr.Instance().TriggerEvent((int)SystemEventDef.System_Open_Window, cmd);
                    }
                    _callBack?.Invoke(window);
                });
            }

            // 关闭指定互斥组的界面,
            public void DoCloseWindowByGroup(int nGroup)
            {
                for (int i = 0; i < m_UIList.Count; ++i)
                {
                    if (m_UIList[i].UIGroup == nGroup)
                    {
                        if (m_UIList[i].DoHide(false))
                            m_TmpList.Add(m_UIList[i]);
                        m_UIList.RemoveAt(i);
                    }
                }

            }
            // 工具类函数，清理掉列表里指定名字的窗口
            PanelBase RemoveWindowFromList(List<PanelBase> winList, string strName)
            {
                foreach (var win in winList)
                {
                    if (win.PanelName == strName)
                    {
                        winList.Remove(win);
                        return win;
                    }
                }
                return null;
            }
            //关闭窗口
            public bool DoCloseWindow(string strName)
            {

                var win = RemoveWindowFromList(m_UIList, strName);
                if (win != null)
                {
                    if (m_bHideVisible)
                    {
                        win.DoFaraway();
                        //DoResortWindow();
                    }
                    else
                    {
                        if (win.DoHide(false))
                            m_TmpList.Add(win);
                    }

                    return true;
                }
                return false;
            }

            // 对窗口重新排序
            public void DoResortWindow()
            {
                int sortOrder = 0;//最上层 全屏界面order
                PanelBase topFullWindow = null;

                for (int i = 0; i < m_UIList.Count; ++i)
                {
                    if (m_UIList[i] != null)
                    {
                        m_UIList[i].SetCanvasEnabled(true);
                        m_UIList[i].DoResetOrder(m_nLayerZero + i * 10 + 1);
                        if (m_UIList[i].IsFullWindow())
                        {
                            if (sortOrder < m_UIList[i].SortOrder)
                            {
                                sortOrder = m_UIList[i].SortOrder;
                                topFullWindow = m_UIList[i];
                            }
                        }

                        if (m_bHideVisible)
                        {
                            if (i != m_UIList.Count - 1) // 除了最后一层，前面的都挪到看不到的位置
                            {
                                m_UIList[i].DoFaraway();
                            }
                        }
                    }
                }

                for (int i = 0; i < m_UIList.Count; ++i)
                {
                    var win = m_UIList[i];
                    if (win != null)
                    {
                        win.IsCoverUp = sortOrder > win.SortOrder;
                        if (win.IsCoverUp)
                        {
                            m_UIList[i].DoFaraway();
                            m_UIList[i].SetCanvasEnabled(false);
                        }
                    }
                }

                bool isShowBg = false;

                if (topFullWindow != null)
                    isShowBg = topFullWindow.IsShowBg();

                if (isShowBg)
                    m_LayerGroupBack?.DoShow();
                else
                    m_LayerGroupBack?.DoHide(true);

            }
            public void GetNavigateList(List<PanelBase> navigateList)
            {
                for (int i = 0; i < m_UIList.Count; ++i)
                {
                    if (m_UIList[i] != null && m_UIList[i].IsNeedNavigate())
                        navigateList.Add(m_UIList[i]);
                }
            }

            public bool IsHaveFullWindow()
            {
                for (int i = 0; i < m_UIList.Count; ++i)
                {
                    if (m_UIList[i] != null && m_UIList[i].IsFullWindow())
                        return true;
                }
                return false;
            }
            public bool IsShowComBg()
            {
                for (int i = 0; i < m_UIList.Count; ++i)
                {
                    if (m_UIList[i] != null && m_UIList[i].IsShowBg())
                        return true;
                }
                return false;
            }

            public void QuickNavCloseWindows()
            {
                List<PanelBase> list = new List<PanelBase>();
                for (int i = 0; i < m_UIList.Count; ++i)
                {
                    if (m_UIList[i] != null && !m_UIList[i].IsQuickNavSkipClose())
                    {
                        list.Add(m_UIList[i]);
                    }
                }
                for (int i = 0; i < list.Count; ++i)
                {
                    DoCloseWindow(list[i].PanelName);
                }
            }

            public void AddUIList(List<PanelBase> uiList)
            {
                for (int i = 0; i < m_UIList.Count; ++i)
                {
                    if (m_UIList[i] != null)
                        uiList.Add(m_UIList[i]);
                }
            }

            // 预加载窗口，初始化的时候放到tmplist里去
            public void DoPreloadWindow(string strName)
            {
                if (IsWindowOpen(strName))
                    return;

                OpenWindowByName(strName, false, (window) =>
                {
                    if (window != null) // 走到这里，肯定是不显示的
                    {
                        return;
                    }
                    CreateWindow(strName, (win) =>
                    {

                        // 直接打开关闭一下，这样加载一下窗口第一次开启的动态组件创建逻辑，分页默认开启第一个
                        DoOpenWindow(strName, null, (_win) =>
                        {
                            DoCloseWindow(strName);

                            XKLog.Log("预加载[" + strName + "]");
                        });
                    });
                });
            }
        }

        Dictionary<int, UICore> m_UIData = new Dictionary<int, UICore>();
        //Dictionary<string, WindowDataDef> m_TableData = new Dictionary<string, WindowDataDef>();

        [HideInInspector]
        public Camera m_uiCamera2d;  // 窗口摄像机
        public Camera m_uiCamera2dBack;  // 窗口摄像机,为透视摄像机
        [HideInInspector]
        public Camera m_uiCamera3d;  // 窗口摄像机,为透视摄像机
        [HideInInspector]
        public Transform m_UIRoot; // 窗口管理器的根节点
        string m_strNavigateName = "";
        string m_strCommonName = "";

        static int GE_CC_RESORT_WINDOW = -1000;
        public void DoGameInitCheck()
        {
            DoInit();
        }
        public void DoInit()
        {
            for (int i = 0; i <= m_nLayerCounter; ++i)
            {
                m_UIData.Add(i, new UICore(i * m_nLayerOffsest));
            }
            ResDataMgr<t_windowdef>.Instance().DoLinkTxt("t_windowdef");
            if (m_UIRoot != null)
                return;
            EventMgr.Instance().AddListener(GE_CC_RESORT_WINDOW, OnResortWindow);
            // 界面用到的2d节点
            var root2d = GameObject.Find("UI2DRoot");
            if (root2d == null)
            {
                string path = @"LogicPrefabs/UI2DRoot";
                var root = ObjectMgr.Instance().CreateObj(path);
                if (root == null)
                {
                    m_uiCamera2d = Camera.main;
                    root = m_uiCamera2d.gameObject;
                    m_UIRoot = root.transform;
                    GameObject.DontDestroyOnLoad(root);
                }
                else
                {
                    GameObject.DontDestroyOnLoad(root);
                    m_UIRoot = root.transform;
                    m_uiCamera2d = root.transform.Find("UICamera").GetComponent<Camera>();
                    m_uiCamera2d.enabled = true;
                }
                CameraMgr.Instance().SetUICamera(m_uiCamera2d);
                CameraMgr.Instance().DoFreshCamera();
                //CameraMgr.Instance().DoRegistToCamera(m_uiCamera2dBack);
                //CameraMgr.Instance().DoRegistToCamera(m_uiCamera3d);
            }
            // 初始化界面层


            // 第三层界面需要设置遮挡不关闭的模式
            //m_UIData[3].SetEnableHideVisible(true);
            //初始化窗口表



        }

        public t_windowdef GetTableDataByName(string strName)
        {
            foreach (var item in GetAllResData())
            {
                if (item.m_strPanelName.Equals(strName))
                    return item;
            }
            XKLog.Log("没有[" + strName + "]的数据");
            return null;
        }

        public void ReloadTableData()
        {
            ResDataMgr<t_windowdef>.Instance().DoReload();
        }

        public void SetCameraDepath(int depth)
        {
            m_uiCamera2d.depth = depth;
        }

        // 窗口是否正在显示
        public bool IsWindowOpen(string strWindowName)
        {
            foreach (var item in m_UIData)
            {
                if (item.Value.IsWindowOpen(strWindowName))
                    return true;
            }
            return false;
        }
        public void EnableGraphicRaycaster(bool enable)
        {
            foreach (var item in m_UIData)
            {
                item.Value.EnableGraphicRaycaster(enable);
            }
        }

        //获取 已经打开的窗口，没有打开的话，不重复打开
        public PanelBase GetWindowByName(string strWindowName)
        {
            foreach (var item in m_UIData)
            {
                var window = item.Value.GetHaveWindow(strWindowName);
                if (window != null)
                    return window;
            }
            return null;
        }

        // 关闭指定大层的窗口
        // nLayer = -1 关闭所有层
        public void DoHideAllWindowByLayer(int nLayer, bool bSave = true)
        {
            if (nLayer == -1)
            {
                foreach (var item in m_UIData)
                {
                    item.Value.DoHideAll(bSave);
                }
            }
            else
            {
                if (m_UIData.Count > nLayer)
                    m_UIData[nLayer].DoHideAll(bSave);
            }
            UpdateNavigateBar();
        }
        // 开启指定大层的窗口
        public void DoShowAllWindowByLayer(int nLayer)
        {
            if (nLayer == -1)
            {
                foreach (var item in m_UIData)
                {
                    item.Value.DoShowAll();
                }
            }
            else
            {
                if (m_UIData.Count > nLayer)
                    m_UIData[nLayer].DoShowAll();
            }
            UpdateNavigateBar();
        }

        // 对外接口,开启一个界面，
        // strWindowName window表里定义的这个窗口的名字， strParam 如果需要传进的参数，先用字符串，除非以后有特殊需求再改
        public void DoOpenWindow(string strWindowName, EventParam param = null, Action<PanelBase> OnLoadedHandle = null)
        {
            var data = GetTableDataByName(strWindowName);
            if (data != null)
            {
                m_UIData[data.m_nLayer].DoOpenWindow(strWindowName, param, (panel) =>
                {
                    OnLoadedHandle?.Invoke(panel);
                    UpdateNavigateBar(strWindowName);
                    MakeModify();
                });
            }
            else
                OnLoadedHandle?.Invoke(null);
        }

        // 设置指定层的背景板
        public void DoSetLayerBack(string strWindowName)
        {
            var data = GetTableDataByName(strWindowName);
            if (data != null)
            {
                m_UIData[data.m_nLayer].SetLayerGroupBack(strWindowName);
            }
        }
        // 关闭指定互斥组的窗口

        public void DoCloseWindowByGroup(int nGroup)
        {
            if (nGroup < 0)
                return;
            foreach (var item in m_UIData)
            {
                item.Value.DoCloseWindowByGroup(nGroup);
            }
            UpdateNavigateBar();
        }
        //关闭窗口
        public void DoCloseWindow(string strWindowName)
        {
            foreach (var item in m_UIData)
            {
                if (item.Value.DoCloseWindow(strWindowName))
                {
                    UpdateNavigateBar(strWindowName);
                    item.Value.DoResortWindow();
                    DoBottomPanelTopShow(strWindowName);
                    return;
                }
            }
        }


        // 预加载所有需要预加载的界面,这个放在进游戏的loading里做，选人界面和创建界面不需要
        public void DoPreloadWindow()
        {
            return;

        }

        //得到大层数据
        UICore GetUICore(int nIndex)
        {
            return m_UIData[nIndex];
        }
        // 界面层级重新排序
        public void DoResortWindow()
        {
            DoCameraCheckStart();
            foreach (var item in m_UIData)
            {
                item.Value.DoResortWindow();
            }
            DoCameraCheckEnd();
        }
        void UpdateNavigateBar(string strWindowName = "")
        {
            // 导航栏不能自己更新自己

            if (strWindowName == m_strNavigateName)
                return;
            if (strWindowName == m_strCommonName)
                return;

            UpdateSceneCamara();



            mNavigateShowType = 0;
            var cmd = new EventParamCommon();


            // 刷新导航条状态
            PanelBase win = null;
            List<PanelBase> navigateList = new List<PanelBase>();
            foreach (var item in m_UIData)
            {
                item.Value.GetNavigateList(navigateList);
            }

            foreach (var item in navigateList)
            {
                if (win == null)
                    win = item;
                else
                {
                    if (item && item.SortOrder > win.SortOrder)
                        win = item;
                }
            }
            if (win == null)
                return;
            // 如果最上面的关注界面是1，就需要开启窗口
            switch (win.Navigate)
            {
                case 1:
                    mNavigateType = win.NavigateType;
                    mNavigateShowType = 1;

                    EventParamCommon param = new EventParamCommon();
                    DoOpenWindow(m_strNavigateName, param, (_win) =>
                     {
                         var showCmd = new EventParamCommon();

                     });
                    break;
            }
        }

        //刷新场景相机的显示和隐藏
        void UpdateSceneCamara()
        {
            int cullingMask = -1;
            foreach (var item in m_UIData)
            {
                var isHaveFullWindow = item.Value.IsHaveFullWindow();
                if (isHaveFullWindow)
                {
                    cullingMask = 0;
                    break;
                }
            }

            bool isShowCommonBg = false;
            foreach (var item in m_UIData)
            {
                var isShow = item.Value.IsShowComBg();
                if (isShow)
                {
                    isShowCommonBg = true;
                    break;
                }
            }
            int useCamera = GetTopUseCamera();

            var cmd = new EventParamCommon();
            cmd.AddDataInt("CullingMask", cullingMask);
            cmd.AddDataInt("UseCamera", useCamera);
            //EventMgr.Instance().TriggerEvent(GameEventDef.GE_CC_MAIN_SCENE_CAMERA, cmd);

            if (isShowCommonBg)
                DoSetLayerBack(m_strCommonName);

        }

        void DoBottomPanelTopShow(string strWindowName = "")
        {
            if (strWindowName == "")
            {
                return;
            }
            var data = GetTableDataByName(strWindowName);
            if ((LayerType)data.m_nLayer == LayerType.Main || (LayerType)data.m_nLayer == LayerType.Normal)
            {

            }
        }

        PanelBase GetTopPanel()
        {
            PanelBase win = null;
            List<PanelBase> uiList = new List<PanelBase>();
            var mainCore = m_UIData[(int)LayerType.Main];
            var normalCore = m_UIData[(int)LayerType.Normal];
            mainCore.AddUIList(uiList);
            normalCore.AddUIList(uiList);
            foreach (var item in uiList)
            {
                if (win == null)
                    win = item;
                else
                {
                    if (item && item.SortOrder > win.SortOrder)
                        win = item;
                }
            }
            return win;
        }
        int GetTopUseCamera()
        {
            PanelBase win = null;
            List<PanelBase> uiList = new List<PanelBase>();
            var mainCore = m_UIData[(int)LayerType.Main];
            var normalCore = m_UIData[(int)LayerType.Normal];
            mainCore.AddUIList(uiList);
            normalCore.AddUIList(uiList);
            foreach (var item in uiList)
            {
                if (item.UseSceneCamera > 0)
                {
                    if (win == null)
                        win = item;
                    else
                    {
                        if (item.SortOrder > win.SortOrder)
                            win = item;
                    }
                }
            }
            if (win)
                return win.UseSceneCamera;
            return 0;
        }
        // 窗口释放
        // 0-10 可以直接释放， 11loading 必须 手动关闭
        public void DoRelease()
        {
            foreach (var item in m_UIData)
            {
                if (item.Key <= m_CanReleaseCounter)
                    item.Value.DoRelease();
            }
        }

        bool OnResortWindow(int ge, EventParam parameter)
        {
            DoResortWindow();
            return true;
        }
        public void DoEnableCamera(int nType, bool enable)
        {
            switch (nType)
            {
                case 2: // 3d摄像机
                    m_uiCamera3d.gameObject.SetActive(enable);
                    break;
                case 1: //  背景摄像机
                    m_uiCamera2dBack.gameObject.SetActive(enable);
                    break;
                default:// 正常摄像机
                    m_uiCamera2d.gameObject.SetActive(enable);
                    break;
            }
        }
        // 是否隐藏整个界面
        public void DoSetUIShow(bool bShow)
        {
            m_uiCamera2d.gameObject.SetActive(bShow);
            m_uiCamera2dBack.gameObject.SetActive(bShow);

            EnableGraphicRaycaster(bShow);
        }
        public bool IsLayerShow(int layer)
        {
            var core = GetUICore(layer);
            if (core != null)
                return core.IsHaveWindowShow();
            return false;
        }
        public bool IsUIShow()
        {
            return m_uiCamera2d.gameObject.activeInHierarchy;
        }

        public void SetUICamera(Camera car)
        {
            m_uiCamera2d = car;
        }

        public Vector3 GetUIPosition(RectTransform rectTrans, Vector3 pos)
        {
            Vector3 worldPos;
            RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTrans, pos, m_uiCamera2d, out worldPos);
            return worldPos;
        }

        public Vector2 WorldToScreenPoint(Vector3 pos)
        {
            Vector2 screenPos;
            screenPos = m_uiCamera2d.WorldToScreenPoint(pos);
            return screenPos;
        }

        public Vector2 ScreenToWorldPoint(Vector3 pos)
        {
            Vector2 screenPos;
            screenPos = m_uiCamera2d.ScreenToWorldPoint(pos);
            return screenPos;
        }

        public Vector2 WorldToViewportPoint(Vector3 pos)
        {
            Vector2 screenPos;
            screenPos = m_uiCamera2d.WorldToViewportPoint(pos);
            return screenPos;
        }

        //要移动坐标的 父节点和 目标点的世界坐标
        public Vector2 GetUILocalPosition(RectTransform rectTrans, Vector3 pos)
        {
            Vector2 localPos;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTrans, pos, m_uiCamera2d, out localPos);
            return localPos;
        }

        List<t_windowdef> GetAllResData()
        {
            return ResDataMgr<t_windowdef>.Instance().GetResData();
        }
        public void DoForceOpenAllWindowByLayer(int layer, Action callback = null)
        {
            List<t_windowdef> list = new List<t_windowdef>();
            foreach (var item in GetAllResData())
            {
                if (item.m_nLayer == layer)
                    list.Add(item);
            }
            int count = list.Count;
            foreach (var item in list)
            {
                DoOpenWindow(item.m_strPanelName, null, (p) =>
                {
                    count--;
                    if (count == 0)
                        callback?.Invoke();
                });
            }
            UpdateNavigateBar();
        }

        public void DoAddCameraEffect(GameObject objEffect, Vector3 position)
        {
            DoInit();
            DoOpenWindow("CameraEffect", null, (win) =>
            {
                var node = win.gameObject.FindDeepChildByName("Mask");
                objEffect.transform.parent = node.transform;
                objEffect.transform.localPosition = Vector3.zero;
                objEffect.transform.localScale = Vector3.one;
                objEffect.transform.localEulerAngles = Vector3.zero;
                objEffect.AddComponent<UISortingOrder>();
                objEffect.StopOrDestroy();
                node.SetAllChildLayer("UI");
                DoResortWindow();
            });
        }
        #region 摄像机自动关闭逻辑，有问题，先放到这，以后再做
        bool[] m_bCameraEnable = new bool[3];
        public void SetCameraEnable(int nCamra)
        {
            m_bCameraEnable[nCamra] = true;
        }
        public void DoCameraCheckStart()
        {
            //for (int i = 0; i < m_bCameraEnable.Length; ++i)
            //    m_bCameraEnable[i] = false;
        }
        public void DoCameraCheckEnd()
        {
            //if (!m_bCameraEnable[0])
            //    m_uiCamera2d.enabled = false;
            //if (!m_bCameraEnable[1])
            //    m_uiCamera2dBack.enabled = false;
            //if (!m_bCameraEnable[2])
            //    m_uiCamera3d.enabled = false;
        }
        #endregion
        public void DoUpdate()
        {
            if (IsModify)
            {
                DoResortWindow();
                ClearModify();
            }
        }

        public void DoFreshSortWindow()
        {
            MakeModify();
        }

        public void DoToggleWindow(string strName)
        {
            if (IsWindowOpen(strName))
                DoCloseWindow(strName);
            else
                DoOpenWindow(strName);
        }

        public void ShowMessage( string msg)
        {
            var cmd = new EventParamCommon();
            cmd.AddDataString("string", msg);
            DoOpenWindow("MessageBox", cmd);
        }
        #region 窗口缓存机制
        class TmpWindowCore
        {
            public string m_strWindwoName = "";
            public EventParamCommon m_WindowParam;
        }
        List<TmpWindowCore> m_TmpWindow = new List<TmpWindowCore>();
        // 加入堆栈
        public void DoPushWindow(string strWindowName, EventParamCommon param)
        {
            foreach (var item in m_TmpWindow)
            {
                if (item.m_strWindwoName == strWindowName)
                {
                    return;
                }
            }
            var core = new TmpWindowCore();
            core.m_strWindwoName = strWindowName;
            core.m_WindowParam = param;
            m_TmpWindow.Add(core);
        }
        // 弹出堆栈
        public void DoPopWindow(string strWindowName)
        {
            foreach (var item in m_TmpWindow)
            {
                if (item.m_strWindwoName == strWindowName)
                {
                    m_TmpWindow.Remove(item);
                    return;
                }
            }
        }
        public void DoClearTmpWindow()
        {
            m_TmpWindow.Clear();
        }

        public void DoReopenTmpWindow()
        {
            foreach (var item in m_TmpWindow)
            {
                DoOpenWindow(item.m_strWindwoName, item.m_WindowParam);
            }
        }

        public void QuickNavCloseWindows()
        {
            foreach (var item in m_UIData)
            {
                item.Value.QuickNavCloseWindows();
            }
            DoFreshSortWindow();
        }
        #endregion
    }


}